﻿using System;
using System.Web;
using System.Web.Mvc;
using GrapeCity.Windows.SpreadSheet.Data;
using GrapeCity.Spread.Sheets.ExcelIO;
using System.IO;
using Newtonsoft.Json.Linq;
using ExcelIOSample.Models;

namespace ExcelIOSample.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public string Import()
        {
            try
            {
                var file = Request.Files[0];
                var postData = Request.Form;
                ExcelOpenFlags flags = ExcelOpenFlags.NoFlagsSet;
                string password = null, value;

                value = postData["ExcelOpenFlags"];
                if (!string.IsNullOrEmpty(value))
                {
                    try
                    {
                        flags = (ExcelOpenFlags)int.Parse(value);
                    }
                    catch(Exception ex)
                    {
                        return "Invalid open flags: " + ex.Message;
                    }
                }

                value = postData["Password"];
                if (!string.IsNullOrEmpty(value))
                {
                    password = value;
                }

                Importer importer = new Importer();
                string result = importer.ImportExcel(file.InputStream, flags, password);
                importer = null;
                result = HttpUtility.HtmlEncode(result);
                return result;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        [HttpPost]
        public ActionResult Export()
        {
            try
            {
                var postData = Request.Form;
                ExportFileModel model;

                model = Newtonsoft.Json.JsonConvert.DeserializeObject<ExportFileModel>(postData["data"]);

                if (model != null)
                {
                    var fileType = model.exportFileType;
                    Exporter exporter = new Exporter(model.spread);
                    MemoryStream stream = new MemoryStream();
                    string contentType = null;

                    switch (fileType)
                    {
                        case "xlsx":
                            contentType = exportExcelFile(model, exporter, stream);
                            break;

                        case "pdf":
                            contentType = exportPdfFile(model, exporter, stream);
                            break;

                        default:
                            // not supported file types
                            return Json(new { error = "Invalid post data: file type not supported." }, JsonRequestBehavior.AllowGet);
                    }

                    exporter = null;

                    if (contentType != null)
                    {
                        stream.Seek(0, SeekOrigin.Begin);

                        var result = new FileStreamResult(stream, contentType);

                        var fileName = HttpUtility.UrlEncode(GetFileName(model));
                        result.FileDownloadName = fileName;
                        return result;
                    }
                }

                return Json(new { error = "Invalid post data" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(new { error = ex.Message }, JsonRequestBehavior.AllowGet);
            }
        }

        private string exportExcelFile(ExportFileModel model, Exporter exporter, MemoryStream stream)
        {
            var setting = model.excel;
            var value = setting.saveFlags;
            ExcelSaveFlags flags = ExcelSaveFlags.NoFlagsSet;
            string password = null;

            if (!string.IsNullOrEmpty(value))
            {
                try
                {
                    flags = (ExcelSaveFlags)int.Parse(value);
                }
                catch (Exception ex)
                {
                    throw new Exception("Invalid save flags: " + ex.Message);
                }
            }

            value = setting.password;
            if (!string.IsNullOrEmpty(value))
            {
                password = value;
            }

            exporter.SaveExcel(stream, ExcelFileFormat.XLSX, flags, password);

            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        }
        private string exportPdfFile(ExportFileModel model, Exporter exporter, MemoryStream stream)
        {
            var pdfSetting = model.pdf;
            PdfExportSettings setting = GetPdfExportSettings(pdfSetting.setting);

            exporter.SavePdf(stream, setting, pdfSetting.sheetIndexes);

            return "application/pdf";
        }

        private PdfExportSettings GetPdfExportSettings(JObject options)
        {
            PdfExportSettings result = new PdfExportSettings();

            result.Author = (string)options["author"];
            result.Title = (string)options["title"];
            result.Subject = (string)options["subject"];
            result.Creator = (string)options["creator"];
            result.Keywords = (string)options["keywords"];
            result.CenterWindow = (bool)options["centerWindow"];
            result.DisplayDocTitle = (bool)options["displayDocTitle"];
            result.HideMenubar = (bool)options["hideMenubar"];
            result.FitWindow = (bool)options["fitWindow"];
            result.HideToolbar = (bool)options["hideToolbar"];
            result.HideWindowUI = (bool)options["hideWindowUI"];

            return result;
        }

        private string GetFileName(ExportFileModel model)
        {
            if (model != null)
            {
                var fileType = model.exportFileType;
                var extension = "." + fileType;
                var fileName = model.exportFileName;

                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = "export";
                }

                if (!fileName.EndsWith(extension))
                {
                    fileName += extension;
                }

                return fileName;
            }

            return string.Empty;
        }
    }
}